//
//  main.c
//  seed
//
//  Created by 徐志瀚 on 17/10/29.
//  Copyright © 2017年 徐志瀚. All rights reserved.
//

#include "stdio.h"

//C(1)
unsigned char C1[8]={0x8a,0xfe,0x85,0x42,0x45,0x21,0x88,0x14};
unsigned char C2[8]={0x45,0x85,0xfe,0x21,0x8a,0x88,0x42,0x14};
//进位加
void Add(unsigned char X0[4],unsigned char X1[4])
{
    int i;
    unsigned char Y[4];//存储相加的结果
    unsigned char c=0;
    for (i=0;i<4;i++)
    {
        Y[i]=X0[i]+X1[i];
        Y[i]+=c;
        if (Y[i]<X0[i]||Y[i]<X1[i])
        {
            c=1;
        }
        else c=0;
        X1[i]=Y[i];
    }
    
}

//S盒
unsigned char S(unsigned char A,int i)
{
    unsigned char x=0;
    unsigned char n[2]={247,251};
    unsigned char d[2]={169,56};
    int j;
    for (j=0;j<n[i-1]-1;j++)
    {
        A=(A*A)%0xb3;
    }
    if (i==1)
    {
        for (j=0;j<8;j++)
        {
            x^=(A*C1[j])%0xb3;
        }
    }
    else
    {
        for (j=0;j<8;j++)
        {
            x^=(A*C2[j])%0xb3;
        }
    }
    x^=d[i-1];
    return x;
}
//G函数
void G(unsigned char A[4])
{
    int i;
    unsigned char B[4];
    unsigned char m[4]={0xfc,0xf3,0xcf,0x3f};
    for (i=0;i<4;i++)
    {
        B[i]=(S(A[0],1)&m[i%4])^(S(A[1],2)&m[(i+1)%4])^(S(A[2],1)&m[(i+2)%4])^(S(A[3],2)&m[(i+3)%4]);
    }
    for (i=0;i<4;i++)
    {
        A[i]=B[i];
    }
}
//轮函数F
unsigned char * F(unsigned char R[8],unsigned char key[8])
{
    unsigned char X0[4];
    unsigned char X1[4];
    unsigned char k1[4];
    unsigned char k2[4];
    unsigned char c=0;//判断是否进位
    int i;
    //将R_(i-1)分成左32bit，右32bit,将轮子密钥分为左右32bit
    for (i=0;i<4;i++)
    {
        X0[i]=R[i];
        X1[i]=R[i+4];
        k1[i]=key[i];
        k2[i]=key[i+4];
    }
    //和轮子密钥进行异或
    for (i=0;i<4;i++)
    {
        X0[i]^=k1[i];
        X1[i]^=k2[i];
        X0[i]^=X1[i];
    }
    G(X0);
    Add(X0,X1);
    G(X1);
    Add(X0,X1);
    G(X0);
    Add(X0,X1);
    for (i=0;i<8;i++)
    {
        if (i<4)
        {
            R[i]=X0[i];
        }
        else
        {
            R[i]=X1[i];
        }
    }
    return R;
}

//seed算法加密
void Encryption(unsigned char L[8],unsigned char R[8],unsigned char K[16*8])
{
    int i,j;
    unsigned char X;
    unsigned char key[8];
    for (i=0;i<16;i++)
    {
        for (j=0;j<8;j++)
        {
            key[j]=K[16*i+j];
        }
        //先求出每轮的R_i
        for (j=0;j<8;j++)
        {
            X=R[j];
            R[j]=L[j]^F(R,key)[j];
            L[j]=X;
        }
    }
    
}

void main()
{
    unsigned char X[16+1];
    unsigned char L[8];//左64bit
    unsigned char R[8];//右64bit
    unsigned char K[16*8+1];
    unsigned char a;
    int i;
    printf("请输入16字节明文(用空格隔开):");
    for (i=0;i<16;i++)
    {
        scanf("%d",&X[i]);
    }
    for (i=0;i<8;i++)
    {
        L[i]=X[i];
        R[i]=X[i+8];
    }
    fflush(stdin);
    printf("请选择密钥产生方式(1为系统产生,2为手动产生):");
    scanf("%d",&a);
    fflush(stdin);
    switch (a)
    {
        case 1:
        {
            for (i=0;i<128;i++)
            {
                K[i]=i+1;
            }
        }
            break;
        case 2:
        {
            printf("请输入48字节密钥(用空格隔开):\n");
            for (i=0;i<128;i++)
            {
                scanf("%d",&K[i]);
            }
            fflush(stdin);
        }
            break;
    }
    Encryption(L,R,K);
    printf("加密后的结果为:\n");
    for (i=0;i<8;i++)
    {
        printf("%02x ",L[i]);
    }
    for (i=0;i<8;i++)
    {
        printf("%02x ",R[i]);
    }
    printf("\n");
}